package com.cskaoyan.javase.object._6clone.depth;


/**
 * 深度克隆和浅克隆
 * 浅克隆: Object类默认实现的clone方法就是浅克隆
 *      浅克隆意味着,对象中:
 *          基本数据类型成员变量复制一份到新对象
 *          但是引用数据类型成员变量只会拷贝一份引用,该拷贝引用仍然指向原先的对象
 *      所以如果对象中存在引用数据类型成员变量,浅克隆得到的对象不是完全独立的
 *
 * 深度克隆: 与浅克隆相对于的就是深度克隆
 *      深度克隆不管对象中是否存在引用数据类型成员变量
 *      深度克隆都会得到一个完全独立的新对象
 *
 * 如何进行深度克隆呢?
 *      1.深度克隆是在浅克隆的基础上完成的
 *      2.要将对象中引用指向的对象克隆一份
 *      3.将克隆对象中的拷贝引用指向2中克隆得到的对象
 *
 *
 * @since 17:38
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Teacher t = new Teacher(18, 10000, new A(666));
        Teacher cloneTeacher = t.clone();
        t.a.num = 777;
        System.out.println(cloneTeacher.a.num);
        // t.age = 20;
        // System.out.println(cloneTeacher.age);
    }
}

class Teacher implements Cloneable {
    int age;
    double salary;
    A a;

    public Teacher(int age, double salary, A a) {
        this.age = age;
        this.salary = salary;
        this.a = a;
    }

    // 现在要对Teacher类做深度克隆操作
    @Override
    protected Teacher clone() throws CloneNotSupportedException {
        // 1.深度克隆是在浅克隆的基础上完成的
        Teacher cloneTeacher = (Teacher) super.clone();
        // 2.要将对象中引用指向的对象克隆一份
        // 这里就需要克隆A的对象
        A cloneA = a.clone();
        // 3.将克隆对象中的拷贝引用指向2中克隆得到的对象
        cloneTeacher.a  = cloneA;
        return cloneTeacher;
    }
}

class A implements Cloneable{
    int num;
    B b;

    public A(int num) {
        this.num = num;
    }

    @Override
    protected A clone() throws CloneNotSupportedException {
        return (A) super.clone();
    }
}
class B{}